import { youngCore } from "./context";
import { In } from "typeorm";
const _ = require("lodash");
abstract class youngService extends youngCore {
  protected entity: string = null;
  protected searchOption = {
    keywords: [],
    fieldEq: [],
    fieldStatus: {},
    size: 20,
    page: 1,
    order: {},
  };
  /**
   * 获取列表
   * @returns
   */
  async list() {
    this.check();
    const where = await this.where();
    return this.success(await where.getMany());
  }
  /**
   * 拼装SQL
   * @returns
   */
  async where() {
    let where = this.getRepository().createQueryBuilder().where("1 = 1");
    if (this.searchOption.fieldEq.length) {
      this.searchOption.fieldEq.forEach((f) => {
        if (this.body[f]) {
          const p = [];
          p[f] = this.body[f];
          where = where.andWhere(`${f} = :${f}`, p);
        }
      });
    }
    if (this.searchOption.fieldStatus) {
      _.forEach(this.searchOption.fieldStatus, (value, key) => {
        let p = {};
        p[key] = value;
        where = where.andWhere(`${key} = :${key}`, p);
      });
    }
    if (this.searchOption.keywords.length && this.body.keywords) {
      let string = "( ";
      const k = this.body.keywords;
      for (let i = 0; i < this.searchOption.keywords.length; i++) {
        const f = this.searchOption.keywords[i];
        if (i == 0) string += `${f} like "%${k}%"`;
        else string += ` or ${f} like "%${k}%"`;
      }
      string += " )";
      where = where.andWhere(string);
    }
    if (this.searchOption.order || this.body.order) {
      _.forEach(this.searchOption.order, (value, key) => {
        where = where.addOrderBy(key, value.toUpperCase());
      });
      _.forEach(this.body.order, (value, key) => {
        where = where.addOrderBy(key, value.toUpperCase());
      });
    }
    return where;
  }
  /**
   * 分页获取
   * @returns
   */
  async page() {
    this.check();
    const size =
      (this.body.size ? parseInt(this.body.size) : 0) || this.searchOption.size;
    const page =
      (this.body.page ? parseInt(this.body.page) : 0) || this.searchOption.page;
    let where = await this.where();
    where = where.take(size).skip((page - 1) * size);
    const data = await where.getManyAndCount();
    return this.success({
      list: data[0],
      pagination: { total: data[1], page, size },
    });
  }

  /**
   * sql分页获取
   * @param sql 分页获取的sql
   * @param params 分页获取的参数
   * @returns 分页数据
   */
  async sqlPage(sql, params) {
    const { order = { createTime: "desc" }, page = 1, size = 10 } = this.body;
    const limit = (page - 1) * size;
    let orderStr = "order by ";
    _.forEach(order, (val, key) => {
      orderStr += `${key} ${val}`;
    });
    _.trim(orderStr, ",");
    const data = await this.sql(
      `${sql} ${orderStr} limit ${limit},${size}`,
      params
    );
    const total = await this.sql(
      "select count(*) as total from (" + sql + ")  as t1",
      params
    );
    return {
      list: data,
      pagination: {
        total: total.length ? Number(total[0].total) : 0,
        page,
        size,
      },
    };
  }
  /**
   * 详情
   * @returns 单行数据
   */
  async info() {
    this.check();
    const { id } = this.query;
    if (!id) throw new Error("请传入id");
    return await this.getRepository().findOne({ id });
  }
  /**
   * 新增
   * @returns
   */
  async add() {
    this.check();
    await this.getRepository().insert(this.body);
    return this.success(this.body);
  }
  /**
   * 更新
   * @returns
   */
  async update() {
    this.check();
    if (!this.body.id) throw new Error("请传入id");
    await this.getRepository().update({ id: this.body.id }, this.body);
    return this.success();
  }
  /**
   * 删除
   * @returns
   */
  async delete() {
    this.check();
    if (!this.body.ids) throw new Error("请传入ids");
    await this.getRepository().delete({
      id: In(this.body.ids.toString().split(",")),
    });
    return this.success();
  }

  /**
   * 获取数据模型
   */
  getRepository() {
    if (typeof this.entity == "string") {
      return this.app.orm[this.entity];
    } else {
      return this.app.orm.getRepository(this.entity);
    }
  }
  /**
   * 数据库原生语句查询
   * @param sql
   * @param param
   * @returns
   */
  async sql(sql, param) {
    if (!this.app.orm) throw new Error("请先配置数据库链接");
    return await this.app.orm.manager.query(sql, param);
  }
  /**
   * 检测是否注册实体
   */
  check() {
    if (this.entity === null) throw new Error("请指定实体");
  }
  /**
   * 成功返回处理
   * @param data 返回数据
   * @returns
   */
  success(data?) {
    data = data || "请求成功";
    return { code: 1000, data };
  }
  /**
   * 失败返回处理
   * @param msg 错误信息
   * @returns
   */
  error(msg?) {
    return { code: 1001, msg };
  }
}
module.exports = youngService;
